"""
"The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is rpg-textengine (http://code.google.com/p/rpg-textengine/).

The Initial Developer of the Original Code is Devin Jeanpierre (jeanpierreda@gmail.com).

Contributor(s): 
(none)
."
"""
#This is the Core Module
#This is version .1 ALPHA
#Checklist
#Write Code .10
#Test functions
#create game
#Test Balance -Private Beta
#Public Beta
#Release

#Alpha versions are untested for either balance or bugs
#Beta versions are tested for bugs, and will be tested for balance. There may still be some bugs
#Neither Alpha nor Beta versions are quite suitable for personal use
#Final versions have been rigorously tested
#And accompany a game as a full package.
#The game SHOULD be developed FOR the Beta, for balance testing purposes.
#The core module may remain in Alpha or Beta until the game is completed
#Versions .1x-.9x are INCOMPLETE and may not be "fun", or even very long

#OO works!

class Battle:
    import random
    import enemies
    #This is the class for all combat related Things
    #Combat Statistics:
    #   HP
    #   Defense
    #   Base Melee
    #   Base Ranged
    #       Under this, there are Weapon and Misc Modifiers, and a Misc additive
    
    @classmethod
    def battle( cls, BattleStats, *enemies):
        import sys
        import statuseffects
        import specATK
        """This initiates a battle with You, and any number of enemies via *args
        Battlestats and *enemies MUST be instances of Classes.Battler, OR Classes.Player
        And, by the way: You initiate a battle via X=battle(blah...)
        Because the battle returns whether you win, lose, or run away.
        So then you can test whether it was a win or loss via if X...
        if X = 0, you ran away
        if X = 1, you won. if it's -1, you lost"""
        import random
        #TODO: Add multiple Allies Via **Args
        #This is what should be contained in each argument
        #Class containing
        #   Name = str
        #   HP = [intCurrent, intTotalPossible]
        #   TP = [current, totalpossible] #TP = Turn points
        #   Defense = int
        #   BMelee = int
        #   BRanged = int
        #   Equipped = Currentweaponstr
        #   Equipment = {weapon:(intATK, type)} #type (an int) is 0 for Melee, 1 for ranged
        #   XP = [melee, ranged, defense]
        #   Bio = longstringofdescription
        #   Pre-effects
        
        #if BattleStats == []:
        #    BattleStats.append(enemies.Thug)
        print BattleStats.Name +" Has entered battle"
        enemylist = []
        for enemy in enemies: enemylist.append(enemy.Name)
        opponents = []
        for enemy in enemies: opponents.append(enemy)
        #if opponents == []:
        #    opponents.append(enemies.Thug)
        if len(enemylist) >= 2:
            iteration = len(enemylist)
            for enemy in enemylist:
                if iteration >=2: sys.stdout.write(enemy + ", ")
                else: sys.stdout.write("and " + enemy)
                iteration = iteration - 1
            sys.stdout.write(" are your opponents.\n")
        else:
            print enemylist[0]+" is your opponent"
        #Turn count below! (1 is first turn)
        count = 1
        #List of actions to take place each turn below!
        speclist = []
        while BattleStats.HP[1] > 0:
            #This is the main Battle loop...
            Input = ""
            while Input != "1" and Input != "2" and Input != "3":
                #This is the verification loop, if invalid input, returns to start of your turn
                print "You can:"
                if BattleStats.Equipped[0] != "":
                    print "1: Attack with "+BattleStats.Equipped[0],"2: use a Special Attack!" "3: Run away"
                #else: 
                #    print "You must run away! You have nothing equipped!"
                #    
                Input = raw_input()
                if Input == "1":
                    PlayerAttack = BattleStats.ATK(opponents[0])
                    print "You hit for %s damage" % str(PlayerAttack)
                    if opponents[0].HP[0] <= 0:
                        print "You have killed %s" % opponents[0].Name
                        del opponents[0]
                    if opponents == []:
                        return 1
                elif Input == "2":
                    if BattleStats.spec != []:
                        print "Select your attack."
                        iteration = 0
                        for attack in BattleStats.spec:
                            print iteration, attack.func_doc
                            iteration = iteration + 1
                        SpecInput = raw_input()
                        if SpecInput >= 0:
                            BattleStats.spec[int(SpecInput)](BattleStats, opponents, speclist)
                        else: continue
                    else: continue
                    for enemy in opponents:
                        if enemy.HP[0] <= 0:
                            print "You have killed %s." % enemy.Name
                            del opponents[opponents.index(enemy)]
                    
                    
                elif Input == "3":
                    #TODO: Add a "speed" attribute, or something, that determines how easily you can run away
                    if random.randint(0,2) == 1:
                        #Unlike what I used to think, return DOES end a function. This returns "RAN AWAY LIKE A SISSY-BITCH"
                        return 0
                else:
                    print "Invalid input, type 1 or 2, and press enter"
            #ENEMY TURN!
            #For now, all AI does is constantly attack. In version .2 and/or .3, 
            #I plan to make a bit more variation in both attack possibilities
            #and AI choices.
            #To be honest, I haven't really planned out much in the way of future stuff, though I have vague ideas.
            
            #Like naked people. There must be a Naked Class.
            #The naked class is a normal battler, only it entices you with it's intoxicating aroma and sexy figure
            #Except then you realize it's a transsexual.
            for enemy in opponents:
                #NOTE: This is copy-pasted from the player-attack section
                CPUAttack = enemy.ATK(BattleStats)
                BattleStats.HP[0] = BattleStats.HP[0] - CPUAttack
                print "%s hits for %s damage" % (enemy.Name, CPUAttack)
                if BattleStats.HP[0] <= 0:
                    print "You are dead"
                    return -1
                        
            # SPECLIST IS A LIST OF 
            #   0: FUNCTION OF EFFECT
            #   1: TURN NUMBER OF WHEN IT STARTED
            #   2: LIST OF PEOPLE AFFECTED
            for action in speclist:
                action[0](count, action, speclist)
            count = count + 1
            
            
        
    @staticmethod
    def ATK(base, weaponmod, miscmod, miscplus):
        """This calculates total Attack Power"""
        import random
        
        total = base + weaponmod + miscmod
        #dierolls = [random.randrange(1,x+1) for x in total]
        dierolls = []
        while total != 0:
            dierolls.append(random.randint(1,10))
            total = total-1
            
        result = 0
        for roll in dierolls:
            if roll>=6:
                result=result+1
        return result+miscplus
    @staticmethod
    def DEF(AttackValue, Defense):
        """This calculates damage after subtracting Defense"""
        return AttackValue-Defense
    @staticmethod
    def EXP(Damage, OPFORDefLevel):
        """This returns the amount of experience gained from an attack"""
        return Damage*OPFORDefLevel
    
class Skills:
    #This is the class for skills.
    #Skills List:
    #   Cooking
    #   Crafting
    #   Stealth
    #   ???
    @staticmethod
    def EXP(ReqLvl):
        """This returns the experience for doing something, based on the level
        required to do it"""
        return ReqLvl*10
    